# coding=utf-8
"""
Created on 2018年08月31日
"""
import weakref
from util_base.ufo_decorators import processor
from common_base.cmd import CMD
from processor_base.base_processor import BaseProcessor
from util_base.exception import ParamException, UFOException as E
from common_base.errors import AliveError
from common_base.constants import UFOConstant, MaxPage
from service_base.article_service import ArticleService
from setting_base.setting import C
from util import formula


@processor(CMD.CMD_UGC_GET_FOR_YOU_ARTICLE_LIST, internal_access=True)
class ForYou(BaseProcessor):
    """
    ForYou
    """
    
    TAG = 'ForYou'
    
    def __init__(self, handler):
        """
        Constructor
        """
        BaseProcessor.__init__(self, handler)
        self._article_service = ArticleService(weakref.proxy(self))
        self.redis_config = C('REDIS_CONFIG')['for_you']
        self._expire_seconds = self.redis_config['expire_seconds']
        self._redis_db = self.redis_config['redis_db']

    def process(self):
        """
        process protocol
        """
        userid = self.alive_cmsdb.get_userid_by_userkey(self.user_key)
        if not userid:
            raise E(AliveError.ERROR_USER_DOES_NOT_EXIST)

        # 每页条数
        articles_page_size = UFOConstant.PAGE_SIZE_FOR_YOU
        comments_page_size = UFOConstant.PAGE_SIZE_FOR_YOU_EACH_ARTICLE_COMMENTS

        # redis key
        redis_key = '%s:for_you_articles:%s' % (CMD.CMD_UGC_GET_FOR_YOU_ARTICLE_LIST, userid)

        # 获取浏览记录
        browse_record = self.redis_engines[self._redis_db].get_set(redis_key)

        if MaxPage.MaxPageSizeForYouArticles * articles_page_size <= len(browse_record):
            # 增加最大浏览数据限制
            db_article_list = list()

        elif self.pull_action:
            # 换一批
            n_articles_page_size = len(browse_record) + articles_page_size
            db_article_list = self.alive_cmsdb.get_for_you_article_list(userid, n_articles_page_size)

        elif self.last_article_id:
            # 分页加载更多
            # 获取帖子当前的分数
            current_article_score = self.alive_cmsdb.get_article_for_you_score_by_articleid(self.last_article_id)
            if not current_article_score:
                # 计算帖子分数(考虑帖子从分数表中被删除的情况, 容错)
                current_article_info = self.alive_cmsdb.get_article_info_by_article_id(self.last_article_id)
                if current_article_info:
                    current_article_score = formula.for_you_article_score(
                        current_article_info.get('cvCount', 0),
                        current_article_info.get('likeCount', 0),
                        current_article_info.get('shareCount', 0),
                        current_article_info.get('commentCount', 0),
                        current_article_info['regTime']
                    )

            n_articles_page_size = len(browse_record) + articles_page_size
            db_article_list = self.alive_cmsdb.get_for_you_article_list(userid, n_articles_page_size, article_score=current_article_score)

        else:
            # 刚启动
            db_article_list = self.alive_cmsdb.get_for_you_article_list(userid, articles_page_size)

        # 去除浏览过的数据
        target_article_list = self.filter_article(browse_record, db_article_list)
        target_article_list = target_article_list[0: articles_page_size]
        if not target_article_list and not self.last_article_id:
            # 清空浏览记录(分页加载更多时不需要清空浏览记录)
            self.redis_engines[self._redis_db].del_keys(redis_key)
            # 初始化数据, 返回第一页内容
            target_article_list = self.alive_cmsdb.get_for_you_article_list(userid, articles_page_size)

        if target_article_list:
            # 保存浏览记录到redis
            redis_value = [e['articleId'] for e in target_article_list]
            if redis_value:
                self.redis_engines[self._redis_db].upsert_set(redis_key, redis_value, expire_seconds=self._expire_seconds)

        # 组装帖子数据
        article_list = self._article_service.batch_deal_articles_return_data(userid, target_article_list, comments_page_size)

        return dict(
            articleList=article_list
        )

    def filter_article(self, browse_record, db_article_list):
        """
        去除浏览过的帖子
        """
        return_article_list = list(filter(lambda each_article: str(each_article['articleId']) not in browse_record, db_article_list))
        return return_article_list

    def _verify_params(self):
        """
        重写父类方法, 作参数校验
        """
        """
        动作: 用户手动下拉为true
        pullAction = false且lastArticleId = 0, 刚启动
        pullAction = true且lastArticleId = 0, 下拉换一批
        lastArticleId != 0时分页加载更多
        """
        self.pull_action = self.params.get('pullAction', False)
        self.last_article_id = self.params.get('lastArticleId', 0)
